package com.googlecode.bip.xml.export;

import java.io.Closeable;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.naming.NamingException;
import org.apache.log4j.Logger;
import com.googlecode.bip.dao.mysql.MySQLDAOFactory;
import cx.ath.choisnet.sql.ConnectionQuery;

/**
 * Handle XML export from MySQL database
 */
//not public
class XMLSurveyConnection
    implements Closeable
{
    private final static Logger logger = Logger.getLogger( XMLSurveyConnection.class );

    public XMLSurveyConnection()
    {
    }

    @Override
    public void close() throws IOException
    {
    }

    @Override
    protected void finalize() throws Throwable
    {
        try { close(); } catch( IOException ignore ) {}
        super.finalize();
    }

    private Connection getConnection()
        throws NamingException, SQLException
    {
        return MySQLDAOFactory.getConnection();
    }

    protected ResultSetCache executeQuery( String sql, String...rows )
        throws NamingException, SQLException
    {
        Connection      connection  = getConnection();
        ResultSetCache  cache       = new ResultSetCache();

        try {
            ConnectionQuery connectionQuery = new ConnectionQuery( connection ) ;

            ResultSet rset = connectionQuery.executeQuery( sql );

            while( rset.next() ) {
                for( String r:rows ) {
                    cache.put( r, rset.getString( r ) );
                    }
                cache.prepareNext();
                }
            }
        finally {
            connection.close();
            }

        return cache;
    }

    /**
     * Cache for {@link ResultSet} 
     */
    class ResultSetCache
    {
        private List<HashMap<String,String>> cacheMap
            = new ArrayList<HashMap<String,String>>();
        private HashMap<String,String> current;
        private int                    currentIndex = 0;

        private ResultSetCache()
        {
            prepareNext();
        }

        private void prepareNext()
        {
            if( current != null ) {
                cacheMap.add( current );
                }
            current = new HashMap<String,String>();
        }

        public boolean next()
        {
            if( currentIndex < cacheMap.size() ) {
                current = cacheMap.get( currentIndex++ );

                logger.info( "next() = TRUE : currentIndex=" + currentIndex + " - cachesize=" + cacheMap.size() );
                return true;
                }

            return false;
        }

        public void close()
        {
            cacheMap.clear();
            current = null;
            currentIndex = Integer.MAX_VALUE;
        }

        private void put( String columnLabel, String string )
        {
            current.put( columnLabel, string );
            //TestCase.assertTrue( current.containsKey( columnLabel ) );
        }

        public String getString( String columnLabel ) throws SQLException
        {
            if( current.containsKey( columnLabel ) ) {
                return current.get( columnLabel );
                }

            throw new SQLException( "column `" + columnLabel + "` not in cache." );
        }

        public int getInt( String columnLabel ) throws SQLException
        {
            String s = getString( columnLabel );

            if( s == null ) {
                return 0;
                }
            else {
                return Integer.parseInt( s );
                }
        }
    }
}
